/**
 * Copyright (c) 2014-2016 www.nryuncang.com. All Rights Reserved.
 */
package com.topisv.tms.service.prioritySend;

import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.shiro.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.topisv.tms.entity.EdiOrder;
import com.topisv.tms.entity.ExpressConfigure;
import com.topisv.tms.entity.OfflineEdiOrder;
import com.topisv.tms.entity.OrderBackTask;
import com.topisv.tms.entity.WarehouseAddress;
import com.topisv.tms.mybatis.Pagination;
import com.topisv.tms.mybatis.service.CommonService;
import com.topisv.tms.repository.EdiOrderDao;
import com.topisv.tms.repository.prioritySend.OfflineEdiOrderDao;
import com.topisv.tms.service.ExpressConfigureService;
import com.topisv.tms.service.WarehouseAddressService;
import com.topisv.tms.service.account.ShiroDbRealm.ShiroUser;

import net.sf.json.JSONObject;

/**
 * 
 *
 * @author <a href=mailto:zhangweize@nryuncang.com>zhangweize</a>
 * @version 1.0.0
 */
@Component
public class PrioritySendService extends CommonService {

	private static final Logger log = LoggerFactory.getLogger(PrioritySendService.class);

	private static List<String> cellNameList = Arrays.asList("WMS订单号", "快递单号", "寄件人姓名", "寄件人省份", "寄件人城市", "寄件人详细地址",
			"寄件人电话", "寄件人手机", "收件人姓名", "收件人省份", "收件人城市", "收件人详细地址", "收件人电话", "收件人手机");
	
	@Autowired
	private EdiOrderDao ediOrderDao;
	@Autowired
	private OfflineEdiOrderDao offlineEdiOrderDao;
	@Autowired
	private WarehouseAddressService warehouseAddressService;
	@Autowired
	private OrderBackTaskService orderBackTaskService;
	@Autowired
	private ExpressConfigureService expressConfigureService;

	/**
	 * 分页查询订单
	 * 
	 * @param param
	 * @return
	 */
	public Pagination loadPage(Map<String, Object> param) {

		Pagination page = myBatisPage("prioritySendMapper.getPrioritySendOrderCount",
				"prioritySendMapper.getPagePrioritySendOrder", param);
		return page;
	}

	/**
	 * 批量重新回传
	 * 
	 *
	 * @param id
	 * @return
	 * @throws Exception
	 *             [参数说明]
	 * @author <a href=mailto:zhangweize@nryuncang.com>zhangweize</a>
	 * @version 1.0.0
	 */
	@SuppressWarnings("unchecked")
	@Transactional(rollbackFor = Exception.class, readOnly = false)
	public boolean batchAgainBack(String id) throws Exception {
		
		try {
			String[] idsArr = id.split("_");
			String orderType = idsArr[0];
			String ordeno = idsArr[1];

			// 系统订单处理
			if ("系统订单".equals(orderType)) {

				// 查询基础信息:订单信息，仓库地址，快递配置信息
				EdiOrder ediOrder = ediOrderDao.findByOrdeno(ordeno);
				WarehouseAddress warehouseAddress = warehouseAddressService.findByWarehouseCode(ediOrder.getWarehouseCode());
				ExpressConfigure expressConfigure = expressConfigureService.findByWarehouseAndCompany(ediOrder.getWarehouseCode(), "TTKDEX");
				
				if(expressConfigure == null ){
					 expressConfigure = expressConfigureService.findByWarehouseAndCompany("HZTT", "TTKDEX");
				}
				
				// 封装成对象
				OfflineEdiOrder oEdiOrder = new OfflineEdiOrder();
				oEdiOrder.setOrdeno(ediOrder.getOrdeno());
				oEdiOrder.setMailNo(ediOrder.getMailNo());
				oEdiOrder.setSendna(warehouseAddress.getContact());
				oEdiOrder.setSendProvna(warehouseAddress.getProvName());
				oEdiOrder.setSendCityna(warehouseAddress.getCityName());
				oEdiOrder.setSendAddres(warehouseAddress.getAddress());
				oEdiOrder.setSendMobile(warehouseAddress.getMobile());
				oEdiOrder.setSendTeleph("");
				oEdiOrder.setRecena(ediOrder.getRecena());
				oEdiOrder.setProvna(ediOrder.getProvna());
				oEdiOrder.setCityna(ediOrder.getCityna());
				oEdiOrder.setAddres(ediOrder.getAddres());
				oEdiOrder.setMobile(ediOrder.getMobile());
				oEdiOrder.setTeleph(ediOrder.getTeleph());

				// 发送天天订单订单回传接口
				JSONObject resultJsonObject = getTTKDEXResult(oEdiOrder, expressConfigure);
				log.info("{}==WMS天天订单订单回传结果=={}", ordeno, resultJsonObject);

				// 根据接口回传信息更新订单状态
				if ("1000".equals(resultJsonObject.get("code"))) {
					ediOrderDao.updateReturnStatus("success", ordeno);
					return true;
				} else {
					ediOrderDao.updateReturnStatus("fail", ordeno);
					return false;
				}
			} else if ("导入订单".equals(orderType)) {// 导入订单处理

				// 查询基础信息:订单信息，快递配置信息
				OfflineEdiOrder oEdiOrder = offlineEdiOrderDao.findByOrdeno(ordeno);
				ExpressConfigure expressConfigure = expressConfigureService
						.findByWarehouseAndCompany(oEdiOrder.getWarehouseCode(), "TTKDEX");

				// 发送天天订单订单回传接口
				JSONObject resultJsonObject = getTTKDEXResult(oEdiOrder, expressConfigure);
				log.info("{}==导入订单天天订单订单回传结果=={}", ordeno, resultJsonObject);

				// 根据接口回传信息更新订单状态
				if ("1000".equals(resultJsonObject.get("code"))) {
					offlineEdiOrderDao.updateReturnStatus("success", ordeno);
					return true;
				} else {
					offlineEdiOrderDao.updateReturnStatus("fail", ordeno);
					return false;
				}
			}
		} catch (Exception e) {
			log.error("{}==批量回传失败=={}", id, e);
			return false;
		}
		return false;
	}

	/**
	 * 得到天天接口返回结果
	 * 
	 *
	 * @param oEdiOrder
	 * @return
	 * @throws Exception
	 *             [参数说明]
	 * @author <a href=mailto:zhangweize@nryuncang.com>zhangweize</a>
	 * @version 1.0.0
	 */
	public JSONObject getTTKDEXResult(OfflineEdiOrder oEdiOrder, ExpressConfigure expressConfigure) throws Exception {
		
		String params = TTKDEXOrderBackInterfaceService.getJson(oEdiOrder, expressConfigure);
		log.info("{}==天天订单订单回传报文=={}", oEdiOrder.getOrdeno(), params);
		
		String resultStr = TTKDEXOrderBackInterfaceService.getTTKDEXResult(params);
		JSONObject resultJsonObject = JSONObject.fromObject(resultStr);
		
		return resultJsonObject;
	}


	/**
	 * 得到excel表格每列的数据
	 * 
	 *
	 * @param xssfRow
	 * @return [参数说明]
	 * @author <a href=mailto:zhangweize@nryuncang.com>zhangweize</a>
	 * @version 1.0.0
	 */
	private static String getValue(Cell xssfRow) {

		String cellValue = "";
		if (xssfRow == null) {
			return cellValue;
		}
		switch (xssfRow.getCellType()) {
		case XSSFCell.CELL_TYPE_STRING:
			cellValue = xssfRow.getRichStringCellValue().getString().trim();
			break;
		case XSSFCell.CELL_TYPE_BOOLEAN:
			cellValue = String.valueOf(xssfRow.getBooleanCellValue()).trim();
			break;
		case XSSFCell.CELL_TYPE_FORMULA:
			cellValue = xssfRow.getCellFormula();
			break;
		case XSSFCell.CELL_TYPE_NUMERIC:
			cellValue = String.valueOf((int) xssfRow.getNumericCellValue());
			break;
		case XSSFCell.CELL_TYPE_BLANK:
			cellValue = "";
			break;
		default:
			cellValue = "";
		}
		return cellValue;
	}

	/**
	 * 保存导入数据 xls
	 * 
	 *
	 * @param maps
	 * @param sheet
	 *            [参数说明]
	 * @author <a href=mailto:zhangweize@nryuncang.com>zhangweize</a>
	 * @version 1.0.0
	 */
	@SuppressWarnings({ "unused", "unchecked" })
	public String saveExcelRows(List<Object> exceptionList, List<Object> normalList, String message, Sheet sheet)
			throws Exception {

		ShiroUser user = (ShiroUser) SecurityUtils.getSubject().getPrincipal();
		
		//其他列校验异常信息
		String exceptionCheckMessage = "";
		
		//订单号异常信息
		String exceptionKeyMessage = "";
		
		//其他异常信息
		String exceptionMessage = "";
		
		//取第一行的列名
		Row hssfRowFirst = sheet.getRow(0);
		
		//校验第一行的列数长度是否满足
		int columns = hssfRowFirst.getLastCellNum();
		if (columns < 14) {
			throw new RuntimeException("excel列表列数小于14列");
		}
		
		//	校验第一行的列的名称是否符合模板
		Map<String,Object> cellMap = new HashMap<>() ;
		for (int column=0; column < columns; column++){
			String cellValue = getValue(hssfRowFirst.getCell(column));
			if(cellNameList.contains(cellValue)) {
				cellMap.put(cellValue, column);
			}
		}
		if (cellMap.size() < 14){
			throw new RuntimeException("excel模板不对");
		}
		
		//从第二行开始取数据
		for (int rowNum = 1; rowNum <= sheet.getLastRowNum(); rowNum++) {
			Row hssfRow = sheet.getRow(rowNum);
			if (hssfRow != null) {
				OfflineEdiOrder oEdiOrder = new OfflineEdiOrder();
				oEdiOrder.setOrderType("导入订单");
				oEdiOrder.setOrdeno(getValue(hssfRow.getCell((int)cellMap.get("WMS订单号"))));
				oEdiOrder.setMailNo(getValue(hssfRow.getCell((int)cellMap.get("快递单号"))));
				oEdiOrder.setSendna(getValue(hssfRow.getCell((int)cellMap.get("寄件人姓名"))));
				oEdiOrder.setSendProvna(getValue(hssfRow.getCell((int)cellMap.get("寄件人省份"))));
				oEdiOrder.setSendCityna(getValue(hssfRow.getCell((int)cellMap.get("寄件人城市"))));
				oEdiOrder.setSendAddres(getValue(hssfRow.getCell((int)cellMap.get("寄件人详细地址"))));
				oEdiOrder.setSendMobile(getValue(hssfRow.getCell((int)cellMap.get("寄件人手机"))));
				oEdiOrder.setSendTeleph(getValue(hssfRow.getCell((int)cellMap.get("寄件人电话"))));
				oEdiOrder.setRecena(getValue(hssfRow.getCell((int)cellMap.get("收件人姓名"))));
				oEdiOrder.setProvna(getValue(hssfRow.getCell((int)cellMap.get("收件人省份"))));
				oEdiOrder.setCityna(getValue(hssfRow.getCell((int)cellMap.get("收件人城市"))));
				oEdiOrder.setAddres(getValue(hssfRow.getCell((int)cellMap.get("收件人详细地址"))));
				oEdiOrder.setMobile(getValue(hssfRow.getCell((int)cellMap.get("收件人手机"))));
				oEdiOrder.setTeleph(getValue(hssfRow.getCell((int)cellMap.get("收件人电话"))));

				// 校验是否为空
				if (checkParam(oEdiOrder)) {
					
					try {
						oEdiOrder.setOperateor(user.jobuuid);
						oEdiOrder.setOperateTime(new Date());
						//保存记录
						saveOfflineEdiOrder(oEdiOrder);
						normalList.add(oEdiOrder);
						
					}catch (Exception e2) {
						
						if (e2.toString().indexOf("Duplicate entry") > -1 && e2.toString().indexOf("for key 'offline_ordeno'") > -1) {
							exceptionKeyMessage = "订单号重复错误;";
						} else {
							exceptionMessage = "其他错误;";
						}
						exceptionList.add(oEdiOrder);
						log.error("线下订单导入异常日志",e2);
					}
				} else {
					exceptionCheckMessage = "请检查某列值为空;";
					exceptionList.add(oEdiOrder);
				}
			}
		}
		message = new StringBuilder().append(message).append(exceptionKeyMessage).append(exceptionCheckMessage).append(exceptionMessage).toString();
		return message;
	}

	/**
	 * 保存线下订单
	 * 
	 *
	 * @param oEdiOrder
	 *            [参数说明]
	 * @author <a href=mailto:zhangweize@nryuncang.com>zhangweize</a>
	 * @version 1.0.0
	 */
	@Transactional(readOnly = false, rollbackFor = Exception.class)
	public void saveOfflineEdiOrder(OfflineEdiOrder oEdiOrder) throws Exception {
		offlineEdiOrderDao.save(oEdiOrder);

		OrderBackTask task = new OrderBackTask();
		task.setType("导入订单");
		task.setRelatedNo(oEdiOrder.getOrdeno());
		task.setCreatedTime(new Date());
		orderBackTaskService.saveTask(task);
	}


	/**
	 * 
	 * 校验每一列
	 *
	 * @param oEdiOrder
	 * @return [参数说明]
	 * @author <a href=mailto:zhangweize@nryuncang.com>zhangweize</a>
	 * @version 1.0.0
	 */
	public boolean checkParam(OfflineEdiOrder oEdiOrder) {
		if ("".equals(oEdiOrder.getOrdeno()) || "null".equals(oEdiOrder.getOrdeno())) {
			return false;
		}
		if ("".equals(oEdiOrder.getMailNo()) || "null".equals(oEdiOrder.getMailNo())) {
			return false;
		}
		if ("".equals(oEdiOrder.getSendna()) || "null".equals(oEdiOrder.getSendna())) {
			return false;
		}
		if ("".equals(oEdiOrder.getSendProvna()) || "null".equals(oEdiOrder.getSendProvna())) {
			return false;
		}
		if ("".equals(oEdiOrder.getSendCityna()) || "null".equals(oEdiOrder.getSendCityna())) {
			return false;
		}
		if ("".equals(oEdiOrder.getSendAddres()) || "null".equals(oEdiOrder.getSendAddres())) {
			return false;
		}
		if (("".equals(oEdiOrder.getSendMobile()) || "null".equals(oEdiOrder.getSendMobile()))
				&& ("".equals(oEdiOrder.getSendTeleph()) || "null".equals(oEdiOrder.getSendTeleph()))) {
			return false;
		}
		if ("".equals(oEdiOrder.getRecena()) || "null".equals(oEdiOrder.getRecena())) {
			return false;
		}
		if ("".equals(oEdiOrder.getProvna()) || "null".equals(oEdiOrder.getProvna())) {
			return false;
		}
		if ("".equals(oEdiOrder.getCityna()) || "null".equals(oEdiOrder.getCityna())) {
			return false;
		}
		if ("".equals(oEdiOrder.getAddres()) || "null".equals(oEdiOrder.getAddres())) {
			return false;
		}
		if (("".equals(oEdiOrder.getMobile()) || "null".equals(oEdiOrder.getMobile()))
				&& (("".equals(oEdiOrder.getTeleph()) || "null".equals(oEdiOrder.getTeleph())))) {
			return false;
		}
	
		return true;
	}
}
